﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Practices.CompositeUI.UIElements;
using SCSFContrib.CompositeUI.WPF.UIElements;

namespace WPFCABShell.Shell.Services
{
	/// <summary>
	/// A <see cref="IUIElementAdapterFactory"/> that produces adapters for <see cref="GroupingItemsControl"/>s
	/// or for <see cref="DependencyObject"/>s hosted inside of <see cref="ItemsControl"/>s.
	/// </summary>
	public sealed class GroupingItemsControlUIAdapterFactory : IUIElementAdapterFactory
	{
		/// <summary>
		/// Gets an adapter for <paramref name="uiElement"/>.
		/// </summary>
		/// <param name="uiElement">
		/// The UI element for which an adapter is required.
		/// </param>
		/// <returns>
		/// The UI element adapter.
		/// </returns>
		public IUIElementAdapter GetAdapter(object uiElement)
		{
			//we can't possibly adapt anything that isn't a DependencyObject
			if (uiElement is DependencyObject)
			{
				//first check if uiElement is an ItemsControl
				ItemsControl itemsControl = uiElement as ItemsControl;

				if (itemsControl != null)
				{
					return new GroupingItemsControlUIAdapter(itemsControl);
				}

				//next check if uiElement is hosted inside an ItemsControl
				DependencyObject dependencyObject = uiElement as DependencyObject;
				Debug.Assert(dependencyObject != null);
				itemsControl = LogicalTreeHelper.GetParent(dependencyObject) as ItemsControl;

				if (itemsControl != null)
				{
					return new ItemsControlChildUIAdapter(dependencyObject);
				}
			}

			throw new ArgumentException("uiElement is not an ItemsControl and is not hosted inside an ItemsControl.", "uiElement");
		}

		/// <summary>
		/// Gets a value indicating whether this adapter factory can adapt <paramref name="uiElement"/>.
		/// </summary>
		/// <param name="uiElement">
		/// The UI element that requires adapting.
		/// </param>
		/// <returns>
		/// <see langword="true"/> if <paramref name="uiElement"/> can be adapted by this adapter factory, otherwise
		/// <see langword="false"/>.
		/// </returns>
		public bool Supports(object uiElement)
		{
			if (uiElement == null)
			{
				return false;
			}

			if (uiElement is ItemsControl)
			{
				//we can adapt ItemsControls
				return true;
			}

			if ((uiElement is DependencyObject) && (LogicalTreeHelper.GetParent(uiElement as DependencyObject) is ItemsControl))
			{
				//we can adapt DependencyObjects inside ItemsControls
				return true;
			}

			return false;
		}
	}
}
